unit MedaxForm ;

interface

uses
    Windows,
    Messages,
    SysUtils,
    Classes,
    Graphics,
    Controls,
    Forms,
    Dialogs,
    ComCtrls,
    Menus,
    ExtCtrls,
    Buttons,
    Tabs,
    StdCtrls,
    IniFiles,
    Grids,
    DBGrids,
    DB,
    DBTables,
    DBCtrls,
    MedaxData,
    MedaxObjects,
    ToolWin,
    ImgList,
    VirtualTrees,
    ActnList ;

type
    TMainForm = class( TForm )
        StatusBar : TStatusBar ;
        DrawPopUpMenu : TPopupMenu ;
        N1 : TMenuItem ;
        DrawPopUpcancel : TMenuItem ;
        PCBPopupMenu : TPopupMenu ;
        N2 : TMenuItem ;
        PCBPopUpCancel : TMenuItem ;
        BoxOpenDialog : TOpenDialog ;
        ColorDialog : TColorDialog ;
        ProjectOpenDialog : TOpenDialog ;
        DrawGridMenuItem : TMenuItem ;
        ImageList : TImageList ;
        MainMenu1 : TMainMenu ;
        File1 : TMenuItem ;
        ActionList1 : TActionList ;
        actZoomIn : TAction ;
        actZoomOut : TAction ;
        actOpen : TAction ;
        actNorth : TAction ;
        ToolBar1 : TToolBar ;
        ToolButton7 : TToolButton ;
        ToolButton9 : TToolButton ;
        ToolButton5 : TToolButton ;
        ToolButton2 : TToolButton ;
        ToolButton1 : TToolButton ;
        ToolButton4 : TToolButton ;
        ToolButton8 : TToolButton ;
        ToolButton3 : TToolButton ;
        ToolButton6 : TToolButton ;
        PageControl : TPageControl ;
        TabSheetSchematic : TTabSheet ;
        DrawScrollBox : TScrollBox ;
        DrawPaintBoxV : TPaintBox ;
        DrawPaintBox : TPaintBox ;
        TabSheetPCB : TTabSheet ;
        PCBScrollBox : TScrollBox ;
        PCBPaintBox : TPaintBox ;
        TabSheetGerber : TTabSheet ;
        GerberScrollBox : TScrollBox ;
        GerberPaintBox : TPaintBox ;
        TabSheetShape : TTabSheet ;
        ShapeScrollBox : TScrollBox ;
        ShapePaintBox : TPaintBox ;
        TabSheetBox : TTabSheet ;
        BoxScrollBox : TScrollBox ;
        BoxPaintBox : TPaintBox ;
        TabSheetComponents : TTabSheet ;
        VirtualStringTree1 : TVirtualStringTree ;
        VirtualStringTree2 : TVirtualStringTree ;
        Splitter1 : TSplitter ;
        Action31 : TMenuItem ;
        actNew : TAction ;
        New1 : TMenuItem ;
        procedure PCBPaintBoxPaint( Sender : TObject ) ;
        procedure FormActivate( Sender : TObject ) ;
        procedure DrawPaintBoxPaint( Sender : TObject ) ;
        procedure CloseBtnClick( Sender : TObject ) ;
        procedure ZoomInBtnClick( Sender : TObject ) ;
        procedure ZoomOutBtnClick( Sender : TObject ) ;
        procedure DrawPaintBoxMouseMove( Sender : TObject ; Shift : TShiftState ; X,
            Y : Integer ) ;
        procedure DrawPaintBoxMouseDown( Sender : TObject ; Button : TMouseButton ;
            Shift : TShiftState ; X, Y : Integer ) ;
        procedure ShapeBoxPaint( Sender : TObject ) ;
        procedure TabControlChange( Sender : TObject ) ;
        procedure BoxPaintBoxPaint( Sender : TObject ) ;
        procedure BoxOpenFileBtnClick( Sender : TObject ) ;
        procedure ColorPanelClick( Sender : TObject ) ;
        procedure LayerBtnClick( Sender : TObject ) ;
        procedure PCBPaintBoxMouseDown( Sender : TObject ; Button : TMouseButton ;
            Shift : TShiftState ; X, Y : Integer ) ;
        procedure PCBPaintBoxMouseMove( Sender : TObject ; Shift : TShiftState ; X,
            Y : Integer ) ;
        procedure OpenProjectSpBtnClick( Sender : TObject ) ;
        procedure DrawGridMenuItemClick( Sender : TObject ) ;
        procedure DrawPaintBoxMouseUp( Sender : TObject ; Button : TMouseButton ;
            Shift : TShiftState ; X, Y : Integer ) ;
        procedure actZoomInExecute( Sender : TObject ) ;
        procedure actZoomOutExecute( Sender : TObject ) ;
        procedure actZoomOutUpdate( Sender : TObject ) ;
        procedure actZoomInUpdate( Sender : TObject ) ;
        procedure actNewExecute( Sender : TObject ) ;
    private
        { Private declarations }
    public
        { Public declarations }
    end ;

var
    MainForm : TMainForm ;
    TheProject : TMedaProject ;

implementation

uses DragSignal ;

{$R *.DFM}

procedure TMainForm.actNewExecute( Sender : TObject ) ;
begin
    if TheProject = nil then begin
        TheProject := TMedaProject.Create( 'Work' ) ;
        if TheProject <> nil then begin
            with TheProject do begin
                CreateLayers( [ lcLayout, lcComponent, lcSolder ] ) ;
                CreatePages( [ 0 ] ) ;
                with AddModule( 'Top' ) do begin
                    DrawGridMenuItem.Enabled := True ;
                    DrawGridMenuItem.Checked := Grid ;
                    AddBox( 'U1', '74als', '74ALS00', 85, 65 ) ;
                    PlaceOnPCB( 'U1', 'DIL14', 4000, 5000, lcComponent, drEast ) ;
                    AddBox( 'U2', '74als', '74ALS244', 95, 65 ) ;
                    PlaceOnPCB( 'U2', 'PLCC44', 5000, 5000, lcComponent, drNorth ) ;
                end ;
                AddLayerObject( nil, lcComponent, otHTrace, 4150, 5000, 4675, 8 ) ;
                AddLayerObject( nil, lcSolder, otVTrace, 3850, 5300, 6000, 12 ) ;
            end ;
        end ;
    end ;
end ;

procedure TMainForm.FormActivate( Sender : TObject ) ;
var
    IniFile : TIniFile ;
begin
    if Tag = 0 then begin
        Tag := 1 ;
        TheProject := nil ;
        IniFile := TIniFile.Create( 'c:\Windows\Meda.Ini' ) ;
        // get preferences
        IniFile.Free ;
    end ;
end ;

procedure TMainForm.TabControlChange( Sender : TObject ) ;
begin
    with DrawScrollBox do
        if Visible and ( Tag = 0 ) then begin
            Tag := 1 ;
            HorzScrollBar.Position := ( DrawPaintBox.Width - Width ) div 2 ;
            VertScrollBar.Position := ( DrawPaintBox.Height - Height ) div 2 ;
        end ;

    with PCBScrollBox do
        if Visible and ( Tag = 0 ) then begin
            Tag := 1 ;
            HorzScrollBar.Position := ( PCBPaintBox.Width - Width ) div 2 ;
            VertScrollBar.Position := ( PCBPaintBox.Height - Height ) div 2 ;
        end ;

    with BoxScrollBox do
        if Visible and ( Tag = 0 ) then begin
            Tag := 1 ;
            HorzScrollBar.Position := ( BoxPaintBox.Width - Width ) div 2 ;
            VertScrollBar.Position := ( BoxPaintBox.Height - Height ) div 2 ;
        end ;

    with ShapeScrollBox do
        if Visible and ( Tag = 0 ) then begin
            Tag := 1 ;
            HorzScrollBar.Position := ( ShapePaintBox.Width - Width ) div 2 ;
            VertScrollBar.Position := ( ShapePaintBox.Height - Height ) div 2 ;
        end ;
end ;

procedure TMainForm.CloseBtnClick( Sender : TObject ) ;
begin
    TheProject.Free ;
    Close ;
end ;

procedure TMainForm.DrawPaintBoxPaint( Sender : TObject ) ;
begin
    with DrawPaintBox.Canvas do begin
        Pen.Color := clBlack ;
        Pen.Width := DrawPaintBox.Tag div 8 ;
        Brush.Color := clYellow ; //DrawBoxColorPanel.Color ;
        Brush.Style := bsSolid ;
    end ;
    if assigned( TheProject ) then
        TheProject.CurrentModule.Paint( DrawPaintBox, DrawPaintBoxV ) ;
end ;

procedure TMainForm.PCBPaintBoxPaint( Sender : TObject ) ;
var
    l : TMedaLayer ;
begin
    with PCBPaintBox do begin
        Canvas.Brush.Style := bsSolid ;
        for l := High( TMedaLayer ) downto Low( TMedaLayer ) do begin
            case l of
                lcLayout : begin
//                        if not LayoutBtn.Down then
//                            continue ;
                        Canvas.Pen.Color := clWhite ;
                        Canvas.Pen.Width := Tag div 8 ;
                        Canvas.Brush.Color := clWhite ;
                        Canvas.Brush.Style := bsClear ;
                    end ;
                lcComponent : begin
//                        if not ComponentBtn.Down then
//                            continue ;
                        Canvas.Pen.Color := clGreen ; //CompLayColorPanel.Color ;
                        Canvas.Pen.Width := 1 ;
                        Canvas.Brush.Color := clGreen ; //CompLayColorPanel.Color ;
                        Canvas.Brush.Style := bsSolid ;
                    end ;
                lcSolder : begin
//                        if not SolderBtn.Down then
//                            continue ;
                        Canvas.Pen.Color := clRed ; //SolderLayColorPanel.Color ;
                        Canvas.Pen.Width := 1 ;
                        Canvas.Brush.Color := clRed ; //SolderLayColorPanel.Color ;
                        Canvas.Brush.Style := bsSolid ;
                    end ;
            else
                continue ;
            end ;
            if TheProject <> nil then
                TheProject.PaintLayer( PCBPaintBox, l ) ;
        end ;
    end ;
end ;

procedure TMainForm.ZoomInBtnClick( Sender : TObject ) ;
begin
        {   end else if MainBoxPanel.Visible then begin
            with BoxPaintBox do begin
           if Tag < 32 then
            Tag := Tag * 2 ;
                Invalidate ;
               end ;
           end else if MainShapePanel.Visible then begin
            with ShapePaintBox do begin
           if ShapePaintBox.Tag < 32 then
            Tag := Tag * 2 ;
                Invalidate ;
               end ;
         }
end ;

procedure TMainForm.ZoomOutBtnClick( Sender : TObject ) ;
begin
            {	else if MainBoxPanel.Visible then
                with BoxPaintBox do begin
               if Tag > 16 then
                Tag := Tag div 2 ;
                    Invalidate ;
                   end
             else if MainShapePanel.Visible then
                with ShapePaintBox do begin
               if Tag > 4 then
                Tag := Tag div 2 ;
                    Invalidate ;
             end }
end ;

procedure TMainForm.DrawPaintBoxMouseMove( Sender : TObject ;
    Shift : TShiftState ; X, Y : Integer ) ;
begin
    StatusBar.Panels[ 1 ].Text := IntToStr( ( X + DrawPaintBox.Tag div 2 ) div DrawPaintBox.Tag ) ;
    StatusBar.Panels[ 2 ].Text := IntToStr( ( Y + DrawPaintBox.Tag div 2 ) div DrawPaintBox.Tag ) ;
    StatusBar.Update ;
end ;

procedure TMainForm.DrawPaintBoxMouseUp( Sender : TObject ;
    Button : TMouseButton ; Shift : TShiftState ; X, Y : Integer ) ;
begin
    DrawPaintBox.OnMouseMove := DrawPaintBoxMouseMove ;
end ;

procedure TMainForm.DrawPaintBoxMouseDown( Sender : TObject ;
    Button : TMouseButton ; Shift : TShiftState ; X, Y : Integer ) ;
var
    Element : TMedaElement ;
begin
    if Button <> mbLeft then
        Exit ;
    StatusBar.Panels[ 3 ].Text := '' ;
    StatusBar.Panels[ 4 ].Text := '' ;
    StatusBar.Panels[ 5 ].Text := '' ;
    if TheProject = nil then
        Exit ;
    if TheProject.CurrentModule = nil then
        Exit ;
    Element := TheProject.CurrentModule.HitTest( X, Y, DrawPaintBox.Tag ) ;
    if Element <> nil then
        case Element.EType of
            etPin : begin
                    with Element.Pin do begin
                        StatusBar.Panels[ 3 ].Text := Box.Name ;
                        StatusBar.Panels[ 4 ].Text := Name ;
                        StatusBar.Panels[ 5 ].Text := IntToStr( Number ) ;
                        TSignal.Create( DrawPaintBox, Element.Pin ) ;
                    end ;
                end ;
            etBox, etNet :
                StatusBar.Panels[ 3 ].Text := Element.Name ;
        else
            StatusBar.Panels[ 3 ].Text := '<unknown>' ;
        end ;
end ;

procedure TMainForm.ShapeBoxPaint( Sender : TObject ) ;
var
    sShape, sPad : string ;
    n, nPins, nPinSpacing, nRowSpacing, nColumnSpacing : integer ;
    nPadWidth, nPadHeight, nHoleSize : integer ;
    nBoxWidth, nBoxHeight : integer ;
    nXOrg, nYOrg, nZoom : integer ;
begin
    with ShapePaintBox do begin
        nXOrg := Width div 2 ;
        nYOrg := Height div 2 ;
        nZoom := Tag ;
    end ;
    with MedaxDataModule.Shapes do begin
        try
            sShape := FindField( 'Type' ).AsString ;
            nPins := FindField( 'Pins' ).AsInteger ;
            sPad := FindField( 'Pad' ).AsString ;
            nPinSpacing := FindField( 'PinSpacing' ).AsInteger * nZoom ;
            nRowSpacing := FindField( 'RowSpacing' ).AsInteger * nZoom div 32 ;
            nColumnSpacing := FindField( 'ColumnSpacing' ).AsInteger * nZoom div 32 ;
            nBoxHeight := FindField( 'BoxHeight' ).AsInteger * nZoom div 64 ;
            nBoxWidth := FindField( 'BoxWidth' ).AsInteger * nZoom div 64 ;
        except
            Exit ;
        end ;
    end ;
    with MedaxDataModule.Pads do begin
        try
            FindKey( [ sPad ] ) ;
            nPadHeight := FindField( 'TopPadHeight' ).AsInteger * nZoom div 64 ;
            nPadWidth := FindField( 'TopPadWidth' ).AsInteger * nZoom div 64 ;
            nHoleSize := FindField( 'HoleSize' ).AsInteger * nZoom div 64 ;
        except
            Exit ;
        end ;
    end ;
    with ShapePaintBox.Canvas do begin
        Brush.Color := clWhite ;
        Pen.Color := clBlack ;
        Rectangle( nXOrg - nBoxWidth, nYOrg - nBoxHeight, nXOrg + nBoxWidth, nYOrg + nBoxHeight ) ;
        MoveTo( nXOrg, 0 ) ;
        LineTo( nXOrg, ShapePaintBox.Height ) ;
        MoveTo( 0, nYOrg ) ;
        LineTo( ShapePaintBox.Width, nYOrg ) ;
        Brush.Color := clBlack ;
        Pen.Color := clBlack ;
        Font.Color := clTeal ;
        if LowerCase( sShape ) = 'so' then begin
            Rectangle( nXOrg - nPadWidth - nColumnSpacing div 2, nYOrg - nPadHeight, nXOrg + nPadWidth - nColumnSpacing div 2 + 1, nYOrg + nPadHeight + 1 ) ;
            Rectangle( nXOrg - nPadWidth + nColumnSpacing div 2, nYOrg - nPadHeight, nXOrg + nPadWidth + nColumnSpacing div 2 + 1, nYOrg + nPadHeight + 1 ) ;
        end
        else if LowerCase( sShape ) = 'dil' then begin
            for n := 0 to nPins div 2 - 1 do begin
                nXOrg := ShapePaintBox.Width div 2 + ( n * nPinSpacing - ( nPins div 2 - 1 ) * nPinSpacing div 2 ) div 32000 ;
                Brush.Color := clBlack ;
                Brush.Style := bsSolid ;
                Ellipse( nXOrg - nPadWidth, nYOrg - nPadWidth - nRowSpacing div 2, nXOrg + nPadWidth + 1, nYOrg + nPadWidth - nRowSpacing div 2 + 1 ) ;
                Ellipse( nXOrg - nPadWidth, nYOrg - nPadWidth + nRowSpacing div 2, nXOrg + nPadWidth + 1, nYOrg + nPadWidth + nRowSpacing div 2 + 1 ) ;
                Brush.Color := clSilver ;
                Ellipse( nXOrg - nHoleSize, nYOrg - nHoleSize - nRowSpacing div 2, nXOrg + nHoleSize + 1, nYOrg + nHoleSize - nRowSpacing div 2 + 1 ) ;
                Ellipse( nXOrg - nHoleSize, nYOrg - nHoleSize + nRowSpacing div 2, nXOrg + nHoleSize + 1, nYOrg + nHoleSize + nRowSpacing div 2 + 1 ) ;
                Brush.Style := bsClear ;
                TextOut( nXOrg + nPadWidth, nYOrg + nPadWidth + nRowSpacing div 2, IntToStr( n + 1 ) ) ;
                TextOut( nXOrg + nPadWidth, nYOrg + nPadWidth - nRowSpacing div 2, IntToStr( nPins - n ) ) ;
            end ;
        end
        else if ( LowerCase( sShape ) = 'qfp' ) or ( LowerCase( sShape ) = 'plcc' ) then begin
            nYOrg := ShapePaintBox.Height div 2 ;
            Brush.Color := clBlack ;
            Brush.Style := bsSolid ;
            for n := 0 to nPins div 4 - 1 do begin
                nXOrg := ShapePaintBox.Width div 2 + ( n * nPinSpacing - ( nPins div 4 - 1 ) * nPinSpacing div 2 ) div 32000 ;
                Rectangle( nXOrg - nPadWidth, nYOrg - nPadHeight - nRowSpacing div 2, nXOrg + nPadWidth + 1, nYOrg + nPadHeight - nRowSpacing div 2 + 1 ) ;
                Rectangle( nXOrg - nPadWidth, nYOrg - nPadHeight + nRowSpacing div 2, nXOrg + nPadWidth + 1, nYOrg + nPadHeight + nRowSpacing div 2 + 1 ) ;
            end ;
            nXOrg := ShapePaintBox.Width div 2 ;
            for n := 0 to nPins div 4 - 1 do begin
                nYOrg := ShapePaintBox.Height div 2 + ( n * nPinSpacing - ( nPins div 4 - 1 ) * nPinSpacing div 2 ) div 32000 ;
                Rectangle( nXOrg - nPadHeight - nColumnSpacing div 2, nYOrg - nPadWidth, nXOrg + nPadHeight - nColumnSpacing div 2 + 1, nYOrg + nPadWidth + 1 ) ;
                Rectangle( nXOrg - nPadHeight + nColumnSpacing div 2, nYOrg - nPadWidth, nXOrg + nPadHeight + nColumnSpacing div 2 + 1, nYOrg + nPadWidth + 1 ) ;
            end ;
            if TextHeight( '99' ) < nPinSpacing div 32000 then begin
                nYOrg := ShapePaintBox.Height div 2 ;
                Brush.Style := bsClear ;
                for n := 0 to nPins div 4 - 1 do begin
                    nXOrg := ShapePaintBox.Width div 2 + ( n * nPinSpacing - ( nPins div 4 - 1 ) * nPinSpacing div 2 ) div 32000 ;
                    TextOut( nXOrg + nPadWidth, nYOrg + nPadHeight + nRowSpacing div 2, IntToStr( n + 1 ) ) ;
                    TextOut( nXOrg + nPadWidth, nYOrg + nPadHeight - nRowSpacing div 2, IntToStr( 3 * nPins div 4 - n ) ) ;
                end ;
                nXOrg := ShapePaintBox.Width div 2 ;
                for n := 0 to nPins div 4 - 1 do begin
                    nYOrg := ShapePaintBox.Height div 2 + ( n * nPinSpacing - ( nPins div 4 - 1 ) * nPinSpacing div 2 ) div 32000 ;
                    TextOut( nXOrg + nPadHeight + nColumnSpacing div 2, nYOrg - nPadWidth, IntToStr( nPins div 2 - n ) ) ;
                    TextOut( nXOrg + nPadHeight - nColumnSpacing div 2, nYOrg - nPadWidth, IntToStr( 3 * nPins div 4 + n + 1 ) ) ;
                end ;
            end ;
        end ;
    end ;
end ;

procedure TMainForm.BoxPaintBoxPaint( Sender : TObject ) ;
var
    sLabel, sBox, sPos : string ;
    nBoxWidth, nBoxHeight : integer ;
    //   nPin : integer ;
    nPos, nTextW, nTextH : integer ;
    nXOrg, nYOrg, nZoom : integer ;
begin
    nXOrg := BoxPaintBox.Width div 2 ;
    nYOrg := BoxPaintBox.Height div 2 ;
    nZoom := BoxPaintBox.Tag ;
    with MedaxDataModule.Boxes do begin
        try
            sBox := FindField( 'Box' ).AsString ;
            nBoxHeight := FindField( 'Height' ).AsInteger * nZoom div 2 ;
            nBoxWidth := FindField( 'Width' ).AsInteger * nZoom div 2 ;
        except
            Exit ;
        end ;
    end ;
    with BoxPaintBox.Canvas do begin
        MoveTo( nXOrg, 0 ) ;
        LineTo( nXOrg, BoxPaintBox.Height ) ;
        MoveTo( 0, nYOrg ) ;
        LineTo( BoxPaintBox.Width, nYOrg ) ;

        Pen.Width := nZoom div 16 ;
        Brush.Color := clWhite ;
        Pen.Color := clBlack ;
        Rectangle( nXOrg - nBoxWidth, nYOrg - nBoxHeight, nXOrg + nBoxWidth, nYOrg + nBoxHeight ) ;

        Brush.Style := bsClear ;
        Pen.Color := clBlack ;
        Font.Color := clTeal ;
        Font.Height := -3 * nZoom div 4 ;
    end ;
    with MedaxDataModule.Pins do begin
        try
            SetRange( [ sBox ], [ sBox ] ) ;
            First ;
            while not EOF do begin
                //				nPin := FindField( 'Pin' ).AsInteger * nZoom div 64 ;
                sLabel := FindField( 'Label' ).AsString ;
                sPos := FindField( 'Position' ).AsString ;
                nPos := StrToInt( Copy( sPos, 2, 8 ) ) - 1 ;
                with BoxPaintBox.Canvas do begin
                    nTextH := TextHeight( sLabel ) div 2 ;
                    nTextW := TextWidth( sLabel ) ;
                    case sPos[ 1 ] of
                        'T' : begin
                                MoveTo( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2, nYOrg - nBoxHeight ) ;
                                LineTo( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2, nYOrg - nBoxHeight - nZoom div 2 ) ;
                                TextOut( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2 - nTextH, nYOrg - nBoxHeight + nZoom div 8 + nTextW, sLabel ) ;
                            end ;
                        'R' : begin
                                MoveTo( nXOrg + nBoxWidth, nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 ) ;
                                LineTo( nXOrg + nBoxWidth + nZoom div 2, nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 ) ;
                                TextOut( nXOrg + nBoxWidth - nZoom div 8 - nTextW, nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 - nTextH, sLabel ) ;
                            end ;
                        'B' : begin
                                MoveTo( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2, nYOrg + nBoxHeight ) ;
                                LineTo( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2, nYOrg + nBoxHeight + nZoom div 2 ) ;
                                TextOut( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2 - nTextH, nYOrg + nBoxHeight - nZoom div 8, sLabel ) ;
                            end ;
                        'L' : begin
                                MoveTo( nXOrg - nBoxWidth, nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 ) ;
                                LineTo( nXOrg - nBoxWidth - nZoom div 2, nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 ) ;
                                TextOut( nXOrg - nBoxWidth + nZoom div 8, nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 - nTextH, sLabel ) ;
                            end ;
                    end ;
                end ;
                Next ;
            end ;
            with BoxPaintBox.Canvas do begin
                Font.Color := clMaroon ;
                TextOut( nXOrg - nBoxWidth - TextWidth( sBox ), nYOrg - nBoxHeight - TextHeight( sBox ), sBox ) ;
            end ;
        except
            Exit ;
        end ;
    end ;
end ;

procedure TMainForm.BoxOpenFileBtnClick( Sender : TObject ) ;
var
    IniFile : TIniFile ;
    Parts, Items : TStringList ;
    sText, sBox, sPack, sFamily : string ;
    i, j, n, p, x, y : integer ;
begin
    if BoxOpenDialog.Execute then begin
        IniFile := TIniFile.Create( BoxOpenDialog.FileName ) ;
        with IniFile do begin
            Parts := TStringList.Create ;
            Items := TStringList.Create ;
            ReadSection( 'Parts', Parts ) ;
            sFamily := BoxOpenDialog.FileName ;
            while Pos( '\', sFamily ) > 0 do
                sFamily := Copy( sFamily, Pos( '\', sFamily ) + 1, MAX_PATH ) ;
            if Pos( '.', sFamily ) > 0 then
                Delete( sFamily, Pos( '.', sFamily ), MAX_PATH ) ;
            try
                MedaxDataModule.Families.AppendRecord( [ sFamily ] ) ;
            except
                on EDBEngineError do
                    StatusBar.Panels[ 6 ].Text := ' Key violation in Families ' ;
            end ;
            for i := 0 to Parts.Count - 1 do begin
                sBox := ReadString( Parts.Strings[ i ], 'symbol', '' ) ;
                if sBox <> 'BOX' then
                    continue ;
                x := ReadInteger( Parts.Strings[ i ], 'xsize', 6 ) ;
                y := ReadInteger( Parts.Strings[ i ], 'ysize', 12 ) ;
                try
                    MedaxDataModule.Boxes.AppendRecord( [ Parts.Strings[ i ], IntToStr( x ), IntToStr( y ) ] ) ;
                except
                    on EDBEngineError do
                        StatusBar.Panels[ 6 ].Text := ' Key violation in Box ' ;
                end ;
                sPack := ReadString( Parts.Strings[ i ], 'package', '' ) ;
                if Length( sPack ) > 0 then begin
                    if Pos( ',', sPack ) > 0 then begin
                        sBox := Copy( sPack, Pos( ',', sPack ) + 1, 80 ) ;
                        Delete( sPack, Pos( ',', sPack ), 80 ) ;
                    end
                    else
                        sBox := '' ;
                    try
                        MedaxDataModule.Parts.AppendRecord( [ sFamily, Parts.Strings[ i ], Parts.Strings[ i ], '', sPack, sBox ] ) ;
                    except
                        on EDBEngineError do
                            StatusBar.Panels[ 6 ].Text := ' Key violation in Parts ' ;
                    end ;
                end ;
                ReadSection( Parts.Strings[ i ], Items ) ;
                for j := 0 to Items.Count - 1 do begin
                    sText := ReadString( Parts.Strings[ i ], Items.Strings[ j ], '' ) ;
                    if Copy( Items.Strings[ j ], 1, 3 ) = 'top' then begin
                        n := StrToInt( Copy( Items.Strings[ j ], 4, 3 ) ) ;
                        p := Pos( ',', sText ) ;
                        try
                            MedaxDataModule.Pins.AppendRecord( [ Parts.Strings[ i ], Copy( sText, 1, p - 1 ),
                                Copy( sText, p + 1, 16 ), '?', 'T' + IntToStr( n ) ] ) ;
                        except
                            on EDBEngineError do
                                StatusBar.Panels[ 6 ].Text := ' Key violation in Pins ' ;
                        end ;
                    end
                    else if Copy( Items.Strings[ j ], 1, 5 ) = 'right' then begin
                        n := StrToInt( Copy( Items.Strings[ j ], 6, 3 ) ) ;
                        p := Pos( ',', sText ) ;
                        try
                            MedaxDataModule.Pins.AppendRecord( [ Parts.Strings[ i ], Copy( sText, 1, p - 1 ),
                                Copy( sText, p + 1, 16 ), '?', 'R' + IntToStr( n ) ] ) ;
                        except
                            on EDBEngineError do
                                StatusBar.Panels[ 6 ].Text := ' Key violation in Pins ' ;
                        end ;
                    end
                    else if Copy( Items.Strings[ j ], 1, 6 ) = 'bottom' then begin
                        n := StrToInt( Copy( Items.Strings[ j ], 7, 3 ) ) ;
                        p := Pos( ',', sText ) ;
                        try
                            MedaxDataModule.Pins.AppendRecord( [ Parts.Strings[ i ], Copy( sText, 1, p - 1 ),
                                Copy( sText, p + 1, 16 ), '?', 'B' + IntToStr( n ) ] ) ;
                        except
                            on EDBEngineError do
                                StatusBar.Panels[ 6 ].Text := ' Key violation in Pins ' ;
                        end ;
                    end
                    else if Copy( Items.Strings[ j ], 1, 4 ) = 'left' then begin
                        n := StrToInt( Copy( Items.Strings[ j ], 5, 3 ) ) ;
                        p := Pos( ',', sText ) ;
                        try
                            MedaxDataModule.Pins.AppendRecord( [ Parts.Strings[ i ], Copy( sText, 1, p - 1 ),
                                Copy( sText, p + 1, 16 ), '?', 'L' + IntToStr( n ) ] ) ;
                        except
                            on EDBEngineError do
                                StatusBar.Panels[ 6 ].Text := ' Key violation in Pins ' ;
                        end ;
                    end ;
                end ;
            end ;
            Items.Free ;
            Parts.Free ;
            Free ;
        end ;
    end ;
end ;

procedure TMainForm.ColorPanelClick( Sender : TObject ) ;
begin
    if ColorDialog.Execute then
        ( Sender as TPanel ).Color := ColorDialog.Color ;
    DrawPaintBox.Invalidate ;
    PCBPaintBox.Invalidate ;
end ;

procedure TMainForm.LayerBtnClick( Sender : TObject ) ;
begin
    PCBPaintBox.Invalidate ;
end ;

procedure TMainForm.PCBPaintBoxMouseDown( Sender : TObject ;
    Button : TMouseButton ; Shift : TShiftState ; X, Y : Integer ) ;
begin
    with TheProject, PCBPaintBox do
        if LayerHitTest( CurrentLayer, X * 32 div Tag, Y * 32 div Tag ) then
            Cursor := crUpArrow
        else
            Cursor := crDefault ;
end ;

procedure TMainForm.PCBPaintBoxMouseMove( Sender : TObject ;
    Shift : TShiftState ; X, Y : Integer ) ;
begin
    StatusBar.Panels[ 1 ].Text := IntToStr( X * 32 div PCBPaintBox.Tag ) + ' mils' ;
    StatusBar.Panels[ 2 ].Text := IntToStr( Y * 32 div PCBPaintBox.Tag ) + ' mils' ;
    StatusBar.Update ;
end ;

procedure TMainForm.OpenProjectSpBtnClick( Sender : TObject ) ;
begin
    ProjectOpenDialog.Execute ;
end ;

{
procedure TMainForm.PartsTreeViewDblClick( Sender : TObject ) ;
begin
    if PartsTreeView.Selected <> nil then begin
        StatusBar.Panels[ 3 ].Text := PartsTreeView.Selected.Text ;
        with PartsTreeView.Selected do
            if DrawScrollBox.Visible and ( Data <> nil ) then
                case TMedaElement( Data ).EType of
                    etModule :
                        TheProject.CurrentModule := TMedaModule( Data ) ;
                    etBox : begin
                            DrawScrollBox.HorzScrollBar.Position := TMedaBox( Data ).X ;
                            DrawScrollBox.VertScrollBar.Position := TMedaBox( Data ).Y ;
                        end ;
                end
            else begin
                if Text = 'Modules' then
                    PageControl.ActivePage.PageIndex := 1
                else if Text = 'Layers' then
                    PageControl.ActivePage.PageIndex := 2 ;
                TabControlChange( Sender ) ;
            end ;
    end
end ;
}

procedure TMainForm.DrawGridMenuItemClick( Sender : TObject ) ;
begin
    TheProject.CurrentModule.Grid := not TheProject.CurrentModule.Grid ;
    DrawGridMenuItem.Checked := TheProject.CurrentModule.Grid ;
    DrawPaintBox.Invalidate ;
end ;

procedure TMainForm.actZoomOutUpdate( Sender : TObject ) ;
begin
    if PageControl.ActivePage = TabsheetSchematic then
        with DrawPaintBox do
            actZoomOut.Enabled := Tag > 4
    else if PageControl.ActivePage = TabsheetPCB then
        with PCBPaintBox do
            actZoomOut.Enabled := Tag > 4
    else
        actZoomOut.Enabled := False ;
end ;

procedure TMainForm.actZoomOutExecute( Sender : TObject ) ;
begin
    if PageControl.ActivePage = TabsheetSchematic then
        with DrawPaintBox do begin
            if Tag > 4 then begin
                Tag := Tag div 2 ;
                with DrawScrollBox do begin
                    HorzScrollBar.Range := HorzScrollBar.Range div 2 ;
                    VertScrollBar.Range := VertScrollBar.Range div 2 ;
                    HorzScrollBar.Position := ( HorzScrollBar.Position + Width div 2 ) div 2 - Width div 2 ;
                    VertScrollBar.Position := ( VertScrollBar.Position + Height div 2 ) div 2 - Height div 2 ;
                end ;
            end ;
            Invalidate ;
        end
    else if PageControl.ActivePage = TabsheetPCB then
        with PCBPaintBox do begin
            if Tag > 4 then begin
                Tag := Tag div 2 ;
                with PCBScrollBox do begin
                    HorzScrollBar.Range := HorzScrollBar.Range div 2 ;
                    VertScrollBar.Range := VertScrollBar.Range div 2 ;
                    HorzScrollBar.Position := ( HorzScrollBar.Position + Width div 2 ) div 2 - Width div 2 ;
                    VertScrollBar.Position := ( VertScrollBar.Position + Height div 2 ) div 2 - Height div 2 ;
                end ;
            end ;
            Invalidate ;
        end
end ;

procedure TMainForm.actZoomInUpdate( Sender : TObject ) ;
begin
    if PageControl.ActivePage = TabsheetSchematic then begin
        with DrawPaintBox do
            actZoomIn.Enabled := Tag < 32
    end
    else if PageControl.ActivePage = TabsheetPCB then begin
        with PCBPaintBox do
            actZoomIn.Enabled := Tag < 32
    end
    else
        actZoomIn.Enabled := False ;
end ;

procedure TMainForm.actZoomInExecute( Sender : TObject ) ;
begin
    if PageControl.ActivePage = TabsheetSchematic then begin
        with DrawPaintBox do begin
            if Tag < 32 then begin
                Tag := Tag * 2 ;
                with DrawScrollBox do begin
                    HorzScrollBar.Range := 2 * HorzScrollBar.Range ;
                    VertScrollBar.Range := 2 * VertScrollBar.Range ;
                    HorzScrollBar.Position := ( HorzScrollBar.Position + Width div 2 ) * 2 - Width div 2 ;
                    VertScrollBar.Position := ( VertScrollBar.Position + Height div 2 ) * 2 - Height div 2 ;
                end ;
            end ;
            Invalidate ;
        end ;
    end
    else if PageControl.ActivePage = TabsheetPCB then begin
        with PCBPaintBox do begin
            if Tag < 32 then begin
                Tag := Tag * 2 ;
                with PCBScrollBox do begin
                    HorzScrollBar.Range := 2 * HorzScrollBar.Range ;
                    VertScrollBar.Range := 2 * VertScrollBar.Range ;
                    HorzScrollBar.Position := ( HorzScrollBar.Position + Width div 2 ) * 2 - Width div 2 ;
                    VertScrollBar.Position := ( VertScrollBar.Position + Height div 2 ) * 2 - Height div 2 ;
                end ;
            end ;
            Invalidate ;
        end ;
    end ;
end ;

end.

